<template>
  <!-- <transition name="el-zoom-in-bottom" mode="out-in"> -->
  <div ref="comSearchRef" class="com-search">
    <div ref="comContentRef" class="com-search-content">
      <el-form ref="formRef" :model="form">
        <el-row>
          <template v-for="item in props.formItem" :key="item.prop">
            <template v-if="item.type === 'input'">
              <el-col :span="24" :xs="24" :sm="6">
                <el-form-item :label="item.label" :prop="item.prop">
                  <el-input v-model="form[item.prop]" :placeholder="item.placeholder" />
                </el-form-item>
              </el-col>
            </template>

            <template v-else-if="item.type === 'select'">
              <el-col :span="24" :xs="24" :sm="6">
                <el-form-item :label="item.label" :prop="item.prop">
                  <el-select v-model="form[item.prop]" :placeholder="item.placeholder">
                    <el-option
                      v-for="(option, index) in item.options"
                      :key="index"
                      :label="option.label"
                      :value="option.value"
                    />
                  </el-select>
                </el-form-item>
              </el-col>
            </template>

            <template v-else-if="item.type === 'date'">
              <el-col :span="24" :xs="24" :sm="12">
                <el-form-item :label="item.label" :prop="item.prop">
                  <el-date-picker
                    v-model="form[item.prop]"
                    type="datetimerange"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    format="YYYY-MM-DD HH:mm:ss"
                    value-format="YYYY-MM-DD HH:mm:ss"
                  />
                </el-form-item>
              </el-col>
            </template>
          </template>

          <el-col :span="24" :xs="24" :sm="6">
            <div class="com-search-options">
              <el-button type="primary" color="var(--color-primary)" @click="handleSearch">搜索</el-button>
              <el-button @click="handleReset">重置</el-button>
            </div>
          </el-col>
        </el-row>
      </el-form>
    </div>
  </div>
  <!-- </transition> -->
</template>

<script setup lang="ts" generic="T extends Record<string, any>">
import { ref, reactive, watch, nextTick, toRaw } from "vue"
import { storeToRefs } from "pinia"
import { animate, JSAnimation } from "animejs"
import useHomeStore from "@/stores/home"
import type { ComSearchFormItem } from "@/types/com-search"
import type { FormInstance } from "element-plus"

const props = defineProps<{
  formItem: ComSearchFormItem[] // 渲染的表单项
  formData: T // 搜索表单数据
}>()

const emit = defineEmits<{
  search: [value: T]
}>()

const homeStore = useHomeStore()
const { showComSearch } = storeToRefs(homeStore)

const formRef = ref<FormInstance | null>(null)
const comSearchRef = ref<HTMLDivElement>()
const comContentRef = ref<HTMLDivElement>()

const form = reactive({ ...props.formData })

const handleSearch = () => {
  emit("search", { ...toRaw(form) } as T)
}

const handleReset = () => {
  formRef.value?.resetFields()
  handleSearch()
}

let animation: JSAnimation | null = null
let isFirstOpen = true

// 计算内容高度
const getContentHeight = () => {
  // 确保元素可见
  comSearchRef.value!.style.display = "block"
  comSearchRef.value!.style.overflow = "hidden"

  return comContentRef.value!.scrollHeight || 0
}

// 执行高度动画
const runHeightAnimation = (targetHeight: number) => {
  if (!comSearchRef.value) return

  // 先停止正在进行的动画
  if (animation) {
    animation.pause()
    animation = null
  }

  // 特殊处理第一次打开
  if (isFirstOpen && targetHeight > 0) {
    comSearchRef.value.style.height = "0px"
    // 强制重绘
    void comSearchRef.value.offsetHeight
    isFirstOpen = false
  }

  animation = animate(comSearchRef.value, {
    height: targetHeight,
    duration: 300,
    easing: "easeInOutQuad",
    onComplete: () => {
      animation = null
    }
  })
}

// 响应式监听展开状态
watch(
  () => showComSearch.value,
  (newVal) => {
    if (!comSearchRef.value) return

    nextTick(() => {
      if (newVal) {
        // 展开动画
        runHeightAnimation(getContentHeight())
      } else {
        // 收起动画
        runHeightAnimation(0)
      }
    })
  },
  { immediate: true }
)
</script>

<style lang="scss" scoped>
.com-search {
  display: none;
  overflow: hidden;
  margin-bottom: 10px;
  will-change: height;

  .com-search-content {
    padding: 16px;
    border-radius: 6px;
    box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
    background-color: var(--color-bg-primary);
  }

  :deep(.el-form) {
    .el-form-item__label {
      width: 33.33%;
      padding: 0 15px;
      text-align: right;
      overflow: hidden;
      white-space: nowrap;
      color: var(--color-black);
    }

    .el-form-item__content {
      width: 66.66%;
    }
  }

  .com-search-options {
    margin-left: 20px;
  }
}
</style>
